# -*- coding: utf-8 -*-
# @Time    : 2024/6/18  18:07
# @Author  : 浪飒
# @FileName: report.py
# @Software: PyCharm
import datetime
import os
import re


def sanitize_url_for_filename(url):
    # 替换不合规字符为短横线
    sanitized_url = re.sub(r'[^\w.-]', '-', url)
    # 替换连续的短横线为单个短横线
    sanitized_url = re.sub(r'-+', '-', sanitized_url)
    # 确保文件名不以短横线开头或结尾
    sanitized_url = sanitized_url.strip('-')
    # 确保文件名长度不超过255个字符（大多数文件系统的限制）
    if len(sanitized_url) > 255:
        sanitized_url = sanitized_url[:255].strip('-')
    return sanitized_url


def report_html(target,vuln_list):
    report_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    # 防止XSS，字符串转义
    vuln_info = ''
    for i in vuln_list:
        # num为数组序号
        num = i[0]
        vuln_name = i[1].replace('<', '&lt;').replace('>', '&gt;')
        vuln_level = i[2].replace('<', '&lt;').replace('>', '&gt;')
        vuln_url = i[3].replace('<', '&lt;').replace('>', '&gt;')
        vuln_desc = i[4].replace('<', '&lt;').replace('>', '&gt;')
        vuln_cve = i[5].replace('<', '&lt;').replace('>', '&gt;')
        vuln_ref = i[6].replace('<', '&lt;').replace('>', '&gt;')
        vuln_fix = i[7].replace('<', '&lt;').replace('>', '&gt;')
        vuln_req = i[8].replace('<', '&lt;').replace('>', '&gt;')
        vuln_res = i[9].replace('<', '&lt;').replace('>', '&gt;')
        vuln_detail = f'''
        <div class="vuln-item" id="vuln{num}">
            <div class="vuln-title" onclick="toggleDetails('details{num}')">
                {num}. {vuln_name} - 威胁等级：{vuln_level}
            </div>
            <div class="vuln-details" id="details{num}">
                <table class="vuln-info">
                    <tr>
                        <th>漏洞地址（URL）</th>
                        <td>{vuln_url}</td>
                    </tr>
                    <tr>
                        <th>漏洞描述（Description）</th>
                        <td>{vuln_desc}</td>
                    </tr>
                    <tr>
                        <th>CVE/CNVD/CNNVD编号</th>
                        <td>{vuln_cve}</td>
                    </tr>
                    <tr>
                        <th>参考链接（Reference）</th>
                        <td>{vuln_ref}</td>
                    </tr>
                    <tr>
                        <th>修复建议（Fixing）</th>
                        <td>{vuln_fix}</td>
                    </tr>
                    <tr>
                        <th>请求包（Request）</th>
                        <td>
                            <pre><code>{vuln_req}</code></pre>
                        </td>
                    </tr>
                    <tr>
                        <th>响应包（Response）</th>
                        <td>
                            <pre><code id="response1">{vuln_res}</code></pre>
                        </td>
                    </tr>
                </table>
            </div>
        </div>
    '''
        vuln_info += vuln_detail
    template_html = """
   <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>猎兔漏洞扫描报告</title>
    <style>
        body {
            font-family: Arial, sans-serif;
        }
        .report-header {
            background-color: #f4f4f4;
            padding: 10px;
            text-align: center;
        }
        .vuln-list {
            margin: 20px;
        }
        .vuln-item {
            margin-bottom: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .vuln-title {
            background-color: #e9ecef;
            padding: 10px;
            cursor: pointer;

        }
        .vuln-details {
            display: none;
            padding: 20px;
            background-color: #f9f9f9;


            
        }
        table.vuln-info {
            border-collapse: collapse;
            margin-top: 10px;
            width: 100%; /* 表格宽度设为100% */
            table-layout: fixed; /* 固定表格布局 */

        }
        table.vuln-info th,
        table.vuln-info td {
            padding: 10px;
            border: 1px solid #ddd;
            text-align: left;
            overflow: auto; /* 添加滚动条 */
            break-word: break-all; /* 允许长单词或空白符序列换行 */
            max-width: 100%; /* 单元格最大宽度设为100% */
            
        }
        table.vuln-info th {
            background-color: #e9ecef;
            font-weight: bold;
            width: 20%; /* 设置表头宽度 */


        }
        pre {
        white-space: pre-wrap; /* 保留换行符 */
        word-wrap: break-word; /* 长单词或不合时宜的空白符序列会被换行 */
    }
    code {
        font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;}
        a{
            text-decoration: none;
            color: #007bff;
        }
        footer {
  margin-top: 30px;
  text-align: center;
  font-size: 13px;
  color: #888;
}
    </style>
</head>
<body>
    <div class="report-header">
        <img src=""  style="width: 20%;" >
        <h1 style="display: inline-block">漏洞扫描报告</h1>
        <h4 style="display: inline-block"> By Hunting Rabbit VulScanner </h4>
        <p style="display: inline-block">&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</p>
        <p style="display: inline-block">报告生成时间："""+report_time+"""</p>




    </div>
    <div class="vuln-list">
        <!-- 漏洞项 -->
""" + vuln_info + """</div>

<footer style="">
  &copy; 2024 Hunting Rabbit VulScanner. All rights reserved.<a href="https://www.langsasec.cn" target="_blank">浪飒安全实验室</a>
  <a href="https://github.com/langsasec/Hunting-Rabbit-VulScanner" target="_blank" style="color: black" class="github-icon" aria-label="访问 Hunting-Rabbit-VulScanner GitHub 仓库">
    <!-- 确保你已经包含了 GitHub 的 SVG 图标文件 -->
<svg viewBox="64 64 896 896" data-icon="github" width="1em" height="1em" fill="currentColor" aria-hidden="true" focusable="false" class=""><path d="M511.6 76.3C264.3 76.2 64 276.4 64 523.5 64 718.9 189.3 885 363.8 946c23.5 5.9 19.9-10.8 19.9-22.2v-77.5c-135.7 15.9-141.2-73.9-150.3-88.9C215 726 171.5 718 184.5 703c30.9-15.9 62.4 4 98.9 57.9 26.4 39.1 77.9 32.5 104 26 5.7-23.5 17.9-44.5 34.7-60.8-140.6-25.2-199.2-111-199.2-213 0-49.5 16.3-95 48.3-131.7-20.4-60.5 1.9-112.3 4.9-120 58.1-5.2 118.5 41.6 123.2 45.3 33-8.9 70.7-13.6 112.9-13.6 42.4 0 80.2 4.9 113.5 13.9 11.3-8.6 67.3-48.8 121.3-43.9 2.9 7.7 24.7 58.3 5.5 118 32.4 36.8 48.9 82.7 48.9 132.3 0 102.2-59 188.1-200 212.9a127.5 127.5 0 0 1 38.1 91v112.5c.8 9 0 17.9 15 17.9 177.1-59.7 304.6-227 304.6-424.1 0-247.2-200.4-447.3-447.5-447.3z"></path></svg>
  </a>
</footer>
    <script>
        function toggleDetails(detailsId) {
            const detailsElement = document.getElementById(detailsId);
            detailsElement.style.display = detailsElement.style.display === 'block' ? 'none' : 'block';
        }

    </script>
</body>
</html>
    """
    report_name = sanitize_url_for_filename(target+'-'+report_time)
    # 如果reports目录不存在，则创建
    if not os.path.exists("reports"):
        os.makedirs("reports")
    with open(f"reports/{report_name}.html", "w", encoding="utf-8") as f:
        f.write(template_html)
